// 文件名：span_unified_params.cpp
// 目的：展示以 std::span 统一接收多种连续内存（std::array、std::vector、原生数组），
//      在原地执行归一化处理，并以只读 span 打印结果；演示子视图再处理。
// API：
//   - normalize(std::span<double>)：就地归一化到 [0,1] 区间（max-min 线性映射）；
//   - printSpan(std::span<const double>)：通用打印，无需拷贝。
// 要点：
//   - 对空/零范围数据做早返回，避免除零；
//   - 同一 normalize/print API 可直接作用于 array、vector、C 数组；
//   - 子视图：对部分数据再做二次 normalize（示例使用 ranges 管道演示子区间概念）。
// 注意：
//   - 末尾的“ranges 管道转 span”的写法在多数实现中无法直接转换：
//       std::span<double> sub = vec | std::views::drop(1) | std::views::take(3);
//     更可移植的方式是：std::span<double> sub = std::span(vec).subspan(1, 3);
//   - 需要 C++20 支持 <span>，使用 ranges 管道还需 <ranges> 头（此示例省略以强调思路）。

#include <array>
#include <iostream>
#include <span>
#include <vector>

void normalize(std::span<double> data) {
    if (data.empty()) return;

    double maxVal = data[0];
    double minVal = data[0];
    for (double v : data) {
        maxVal = std::max(maxVal, v);
        minVal = std::min(minVal, v);
    }
    double range = maxVal - minVal;
    if (range == 0.0) return;

    for (double& v : data) {
        v = (v - minVal) / range;
    }
}

void printSpan(std::span<const double> data) {
    for (double v : data) {
        std::cout << v << ' ';
    }
    std::cout << '\n';
}

int main() {
    std::array<double, 4> arr{2.0, 8.0, 4.0, 10.0};
    std::vector<double> vec{5.0, 3.0, 9.0, 1.0, 4.0};
    double raw[3]{0.5, 0.75, 1.25};

    normalize(arr);
    normalize(vec);
    normalize(raw);

    printSpan(arr);
    printSpan(vec);
    printSpan(raw);

    // 子视图（演示意图）：对 vec 的中间 3 个元素二次归一化
    // 更推荐写法：std::span<double> sub = std::span(vec).subspan(1, 3);
    std::span<double> sub = vec | std::views::drop(1) | std::views::take(3);
    normalize(sub);
    printSpan(vec);

    return 0;
}